package org.wmine.preprocess;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.JRadioButton;
import javax.swing.JButton;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.table.DefaultTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;

import org.wmine.core.IntegerTextField;
import org.wmine.data.Attribute;

import java.util.Iterator;
import java.util.Vector;
public class Binning extends JFrame implements ActionListener
{
	JLabel labelSelectAtrr,labelBins;
	JButton btnOK;
	JComboBox cmbAttr;
	IntegerTextField txtBins;
	JRadioButton radioMean,radioMedian,radioBoundary,radioDepth,radioWidth;
	ButtonGroup bg,bgType;
	JPanel panel;
	DefaultTableModel dtm;
	String tablename;
	public Binning(){}
	public Binning(String []columnNames,DefaultTableModel dtm,String tablename)
	{
		this.dtm=dtm;
		this.tablename=tablename;
		
		//Container c=this.getContentPane();
		panel=new JPanel();
		panel.setLayout(null);
		this.setBounds(280,120,300,360);
		this.setTitle("Binning");
		
		labelSelectAtrr=new JLabel("Select Attribute");
		labelSelectAtrr.setBounds(10,50,100,25);
		
		cmbAttr=new JComboBox();
		for(int i=0;i<columnNames.length;i++)
			cmbAttr.addItem(columnNames[i]);
		cmbAttr.setBounds(120,50,150,25);
		
		
		bgType=new ButtonGroup();
	    radioDepth=new JRadioButton("Equi-Depth");
	    radioWidth=new JRadioButton("Equi-Width");
	    radioDepth.setBounds(40,90,100,25);
	    radioWidth.setBounds(160,90,100,25);
	    radioDepth.addActionListener(new ActionListener()
		{
	    	public void actionPerformed(ActionEvent ae)
		    {
			   	   txtBins.setEnabled(true);
			   	   labelBins.setEnabled(true);
			   	   
			}
	    }); // end of equi depth radio listener
	    
	    radioWidth.addActionListener(new ActionListener()
		{
	    	public void actionPerformed(ActionEvent ae)
		    {
			   	   txtBins.setEnabled(false);
			   	   labelBins.setEnabled(false);
			   	   
			}
	    }); // end of equi width radio listener
	    
	    
	    radioDepth.setSelected(true);
	    bgType.add(radioDepth);
	    bgType.add(radioWidth);
	    
	    labelBins=new JLabel("How Many Bins? ");
		labelBins.setBounds(10,130,100,25);
		
		txtBins=new IntegerTextField();
		txtBins.setBounds(120,130,150,25);
		
		bg=new ButtonGroup();
	    radioMean=new JRadioButton("Smooth By Mean");
	    radioMedian=new JRadioButton("Smooth By Median");
	    radioBoundary=new JRadioButton("Smooth By Boundary");
	    radioMean.setBounds(20,170,150,25);
	    radioMedian.setBounds(20,200,150,25);
	    radioBoundary.setBounds(20,230,150,25);
	    radioMean.setSelected(true);
	      		
	    bg.add(radioMean);
	    bg.add(radioMedian);
	    bg.add(radioBoundary);
	    
	    btnOK=new JButton("OK");
	    btnOK.setBounds(90,280,100,25);
	    btnOK.addActionListener(this);
	    
	    panel.add(labelSelectAtrr);
	    panel.add(cmbAttr);
	    panel.add(labelBins);
	    panel.add(txtBins);
	    panel.add(radioMean);
	    panel.add(radioMedian);
	    panel.add(radioBoundary);
	    panel.add(btnOK);
	    panel.add(radioDepth);
	    panel.add(radioWidth);
	    panel.repaint();
	    
	    this.add(panel);
	}
	
	public void actionPerformed(ActionEvent ae)
	{
		int bins=0;
		String selected=cmbAttr.getSelectedItem().toString();
		int selectedindex=cmbAttr.getSelectedIndex();
		int j=0;	
		int rows=dtm.getRowCount();
		
		if(ContainsMissingValues(dtm,selectedindex)==true)
		{
			JOptionPane.showMessageDialog(null,"Binning cannot be performed on incomplete data");
			this.dispose();
		}
		else
		{
			if(radioDepth.isSelected()==true)
			{
				
				if(txtBins.getText().trim().equals(null) || txtBins.getText().trim().equals(""))
				{
					JOptionPane.showMessageDialog(null,"Error!! No.of Bins cannot be blank!!");
				}
				
				else//(!(txtBins.getText().trim().equals(null)) || !(txtBins.getText().trim().equals("")))
				{
					bins=Integer.parseInt(txtBins.getText().trim());
					if(bins>rows)
					{	//error
						JOptionPane.showMessageDialog(null,"Number of bins > available data");
						txtBins.selectAll();
						txtBins.requestFocus();
					}
					
					else
					{
						String s=null;
						
						s=dtm.getValueAt(Integer.parseInt(""+Math.round(rows-1)),selectedindex).toString().trim();
						for(int i=0;i<s.length();i++)
							if(!(s.charAt(i)>='0' && s.charAt(i)<='9'))
							{
								j=1;
								break;
							}
						if(j==1)
						{
							System.out.print("error: sorting can be performed on real data");
							//error: sorting can be performed on real data
							JOptionPane.showMessageDialog(null,"Error: Operation can be performed only on real data!!");
							
						}
						else if(j==0)
						{
							System.out.print("perform sorting");
							Algorithm algo=new Algorithm(dtm,selectedindex);
							int result=algo.quickSort();
							int result1=0;
							if(result==-1)
							{	JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
								PreprocessPanel.flag=0;
							}
							else
							{
								if(radioMean.isSelected()==true)
								{
									result1=algo.Smooth_By_Means_Median(Integer.parseInt(txtBins.getText()),"mean","depth");
									if(result1==-1)
									{	JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
										PreprocessPanel.flag=0;
									}
									
								}
								else if(radioMedian.isSelected()==true)
								{
									result1=algo.Smooth_By_Means_Median(Integer.parseInt(txtBins.getText()),"median","depth");
									if(result1==-1)
									{
										JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
										PreprocessPanel.flag=0;
									}
								}
								else if(radioBoundary.isSelected()==true)
								{
									result1=algo.Smooth_By_Boundary(Integer.parseInt(txtBins.getText()),"depth");
									if(result1==-1)
									{
										JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
										PreprocessPanel.flag=0;
									}
									
								}
								this.dispose();
															
							}
						}
					}
				}
				/*else
				{
					JOptionPane.showMessageDialog(null,"Error!! No.of Bins cannot be blank!!");
				}*/
			}
			else if(radioWidth.isSelected()==true)
			{
				String s=null;
				
				s=dtm.getValueAt(Integer.parseInt(""+Math.round(rows-1)),selectedindex).toString().trim();
				for(int i=0;i<s.length();i++)
					if(!(s.charAt(i)>='0' && s.charAt(i)<='9'))
					{
						j=1;
						break;
					}
				if(j==1)
				{
					System.out.print("error: sorting can be performed on real data");
					//error: sorting can be performed on real data
					JOptionPane.showMessageDialog(null,"Error: Operation can be performed only on real data!!");
					
				}
				else if(j==0)
				{
					System.out.print("perform sorting");
					Algorithm algo=new Algorithm(dtm,selectedindex);
					int result=algo.quickSort();
					int result1=0;
					if(result==-1)
					{	JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
						PreprocessPanel.flag=0;
					}
					else
					{
						if(radioMean.isSelected()==true)
						{
							
							result1=algo.Smooth_By_Means_Median(0,"mean","width");
							if(result1==-1)
							{	JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
								PreprocessPanel.flag=0;
							}
							
						}
						else if(radioMedian.isSelected()==true)
						{
							result1=algo.Smooth_By_Means_Median(0,"median","width");
							if(result1==-1)
							{
								JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
								PreprocessPanel.flag=0;
							}
						}
						else if(radioBoundary.isSelected()==true)
						{
							result1=algo.Smooth_By_Boundary(0,"width");
							if(result1==-1)
							{
								JOptionPane.showMessageDialog(null,"Error!! In performing Binning");
								PreprocessPanel.flag=0;
							}
							
						}
						this.dispose();
													
					}
				}
				
			}
		}
	}
	boolean ContainsMissingValues(DefaultTableModel dtm, int column)
	{
		if(dtm.getRowCount()>0)
		{
			for(int i=0;i<dtm.getRowCount();i++)
			{
				if(dtm.getValueAt(i,column).toString().trim().equals("?") || dtm.getValueAt(i,column).toString().trim().equals("") || dtm.getValueAt(i,column).toString().trim().equals(null))
					return true;
			}
		}
		return false;	
	}
	
}


